package com.lzh.shellcommand.commands

import com.sun.tools.attach.VirtualMachine
import dnl.utils.text.table.TextTable
import org.jline.utils.Log
import java.io.File
import java.lang.management.RuntimeMXBean
import java.time.Duration
import javax.management.remote.JMXConnector
import javax.management.remote.JMXConnectorFactory
import javax.management.remote.JMXServiceURL

val psTableHeader = arrayOf("PID", "MAIN", "RUNNING", "HEAP", "PORT", "PATH", "JAVA_VERSION")

fun printPsTable(data: Array<Array<String>>) {
    println(">> Spring Boot Process:")
    TextTable(psTableHeader, data).printTable()
}

fun processUserFriendlyTime(mills: Long): String {
    val duration = Duration.ofMillis(mills)
    return duration.toString().substring(2).replace("(\\d[HMS])(?!$)", "$1 ").toLowerCase()
}

fun getPorts(pid: String): String = "lsof -p $pid |grep LISTEN |awk '{print\$8\$9}'".command().lines().joinToString(",")


fun isSpringBootApplication(rmxb: RuntimeMXBean) = rmxb.classPath.contains("spring-boot")


fun localJmxConn(): List<JMXConnector> = VirtualMachine.list().mapNotNull { desc ->
    runCatching {
        val vm = VirtualMachine.attach(desc)
        // no JMX - use agent to enable it
        val remoteProperties = vm.systemProperties
        val separator = remoteProperties.getProperty("file.separator", File.separator)
        vm.loadAgent(remoteProperties.getProperty("java.home") + separator + "lib" + separator + "management-agent.jar")
        val connectorAddress = vm.agentProperties.getProperty("com.sun.management.jmxremote.localConnectorAddress")
        JMXConnectorFactory.connect(JMXServiceURL(connectorAddress))
    }.onFailure {
        Log.debug("conn jmx failure:", it)
    }
}.filter(Result<JMXConnector>::isSuccess).map { x -> x.getOrThrow() }
